
#include "game_application.h"
#include "game_script.h"
#include "game_rms.h"
#include "window_handler.h"
#include "credit_state.h"

#include "util/profiler.h"

// states (used to register states)
#include "gameflow/game_flow_manager.h"
#include "gameflow/ui_state.h"
#include "gameflow/ui_popup.h"
#include "script/scripthelper.h"
#include "dd/dd_man.h"
#include "ui/ui_checkbox.h"
#include "ui/ui_slider.h"

// script execution
#include "game_script.h"
#include "vfs/vfs.h"
//#include "web/server.h"

// graphics and input
#include "graphics/graphics.h"

#include "font/font_manager.h"
#include "font/font.h"
#include "console/console.h"
#include "camera/fb_camera.h"
#include "application/boot_loader.h"

// audio
#include "audio/audio.h"

// localization
#include "lang/strman.h"
#include "lang/swear.h"

// UI
#include "ui/ui_manager.h"
#include "ui/ui_widget.h"
#include "ui/ui_progress.h"
#include "ui/sprite_set.h"

// util
#include "util/filepath.h"
#include "util/log.h"				// log
#include "util/common_macros.h"		// macros
#include "util/mmgr.h"		    
#include "util/timer.h"		    

#ifdef _PLATFORM_ANDROID
	#ifdef __cplusplus
		extern "C"
		{
	#endif
	#include "SDL2/src/core/android/SDL_android.h"
	#ifdef __cplusplus
		}
	#endif
	#include "android/sleipner_android.h"
#endif

#include <stdlib.h>

#include <time.h>
#include <cassert>
using namespace script;
using namespace util;
using namespace gameflow;

// global holder for the game application
// most DRMs will not handle RAII properly for application exit, so do this the dump way
GameApp*	g_pApp = NULL;

GameApp::GameApp(WindowHandler* pHandler, const std::string& Config, const std::string& Log) :
m_pScript(NULL),
m_pRMS(NULL),
m_pWindowHandler(pHandler),
m_pLoadingBackground(NULL),
m_pLoadingProgress(NULL),
m_CurrentRate(0),
m_TargetRate(1000),
m_SavePrecat("bzp"),
m_IsFullscreen(false),
m_TickCounter(0)
{
	assert(pHandler && "No valid window handler!");
    
	// init the log file
	Logger::Instance().Init(Log);
	Logger::Instance().SetAutoFlush(true);
	Logger::Instance().SetVerbose(true);
	_LOG(MSG_INIT, "Logfile created");
}


GameApp::~GameApp()
{
}

bool	GameApp::Quit()
{
	m_pWindowHandler->DestroyWindow();
	return true;
}

bool		GameApp::ResetDevice()
{
	GetHandler()->ResetDevice();
    
	return true;
}

void		GameApp::LoadIniFile(const std::string& File)
{
#ifdef _PLATFORM_WIN32
	m_Config.Load(File);	// loads the config file data
#endif
    
	// init RMS
	m_SavePrecat = GetConfigString("SaveFile", "2dstar");
	m_pRMS =  CreateRMS();		// force a load from the new save-file
	m_pRMS->Load();
    
	// init language
	std::string		DefaultLang	= GetConfigString("Language", "auto");
	bool			Force		= GetConfigBool("ForceLang", false);
	bool			EmptyLang	= strlen(GameRMS::Instance()->GetLanguage()) ==0;
    
	std::string	Lang = "English";
    if(!EmptyLang)
    Lang =  m_pRMS->GetLanguage();
	if (Force || EmptyLang)
	{
#ifdef _PLATFORM_WIN32
		if (strcmpi(DefaultLang.c_str(), "auto")==0)
		{
			LANGID LanguageID = GetUserDefaultUILanguage();
			WORD	Primary =PRIMARYLANGID(LanguageID);
			switch (Primary)
			{
				case LANG_CHINESE:	Lang = "chinese"; break;
				case LANG_JAPANESE:	Lang = "japanese"; break;
				case LANG_KOREAN:	Lang = "korean"; break;
				case LANG_ENGLISH:	Lang = "english"; break;
				case LANG_GERMAN:	Lang = "german"; break;
				case LANG_FRENCH:	Lang = "french"; break;
				case LANG_SPANISH:	Lang = "spanish"; break;
                    //case LANG_ITALIAN:	Lang = "italian"; break;
				case LANG_SWEDISH:	Lang = "swedish"; break;
				case LANG_DUTCH:	Lang = "dutch"; break;
				case LANG_PORTUGUESE:	Lang = "portuguese"; break;
				default:
					Lang = GetDefaultLocalization();
			}
		} else
		{
			Lang = DefaultLang; // nope; revert to default (and hope it's there)
		}
        
		// verify that localization file exists
		if (!FilePath::FileExists(GetLocalizationFile(Lang)))
			Lang = GetDefaultLocalization(); // nope; revert to default (and hope it's there)
#endif //_PLATFORM_WIN32
	}
	GameRMS::Instance()->SetLanguage(Lang);

	lang::StrMan::Instance().LoadLangBin(GetLocalizationFile(Lang));

}

std::string			GameApp::GetConfigString(const std::string& Name, const std::string& Default)
{
	return m_Config.GetString("Config", Name, Default);
}
float				GameApp::GetConfigFloat(const std::string& Name, float Default)
{
	return m_Config.GetFloat("Config", Name, Default);
}

int					GameApp::GetConfigInt(const std::string& Name, int Default)
{
	return m_Config.GetInt("Config", Name, Default);
}

bool				GameApp::GetConfigBool(const std::string& Name, bool Default)
{
	return m_Config.GetBool("Config", Name, Default);
}

bool		GameApp::Init()
{
	// I need to load this first, otherwise localization file can't find by the system
	LoadArchives();
    
	// load the ini file
	LoadIniFile("config.ini");
    
	InitSystems();
    
	
    
	if (!InitGraphics())
	{
		return false;
	}
    
	// initialize the common rand function
	srand( (unsigned)time(NULL) );
    
	console::Console::Instance().Do("ReloadGame()");		// force it to reload the game scripts
	OnBindKeys();
    
	OnCreateStates();
	// start the jump to state
    
	if (m_pLoadingBackground)
	{
		m_pLoadingBackground->SetIsVisible(false);		
		m_pLoadingBackground = NULL;
	}
	return true;
}
bool		GameApp::Shutdown()
{
	AUDIO().Shutdown();

    //	web::Server::Instance().Shutdown();
	_LOG(MSG_INIT, "Server connection shutdown");
    
	// shutdown gameflow + current game
	gameflow::GameFlowManager::Instance().Shutdown();
	_LOG(MSG_INIT, "Gameflow manager shutdown");
    
	// shut down font
	FontManager::Instance().Shutdown();
	_LOG(MSG_INIT, "Font manager shutdown");
    
	// shut down console
	console::Console::Instance().Shutdown();
	_LOG(MSG_INIT, "Console shutdown");
    
	// shutdown camera before D3D
	UTIL_SAFE_DELETE(m_pCamera);
    
	ui::UIManager::Instance().Shutdown();
	_LOG(MSG_INIT, "UI shutdown");
    
	Graphics::SHUTDOWN();
	_LOG(MSG_INIT, "Graphics shutdown");
    
	UTIL_SAFE_DELETE(m_pScript);
    
	if (m_pRMS && m_pRMS->IsLoaded())
		m_pRMS->Save();
	UTIL_SAFE_DELETE(m_pRMS);
    
#ifdef _PLATFORM_ANDROID
	Android_JNI_SendMessage( (int)FUNC_onHardQuit,0);   	
#endif
    
	return true;
}

bool		GameApp::Tick()
{
    
    
	// Let the current gamestate update itself
	TIMER().Tick();
	float	dt = TIMER().Delta();
	m_TickCounter += dt;

	   
#if  defined(_PLATFORM_IOS) || defined(_PLATFORM_ANDROID)
	const float FR = 1.0f/32.0f;
#else
	const float FR = 1.0f/60.0f;
#endif
    
	if( m_TickCounter > FR)
	{	
		m_pWindowHandler->Tick(m_TickCounter);
        
#if defined( _PLATFORM_IOS) || defined(_PLATFORM_ANDROID)
        if (!m_pWindowHandler->HasFocus()) 
        {
            GetHandler()->UpdateOS();	
            return !IsDestroyed();
        }
#endif
        
		if (!m_pWindowHandler->IsDestroyed())
		{
			START_PROFILER()
			gameflow::GameFlowManager::Instance().Tick(m_TickCounter);
            
			END_PROFILER();
		}
		
		m_TickCounter = 0;
	}
	GetHandler()->UpdateOS();	
    
	
	
	return !IsDestroyed();
}

bool		GameApp::StartOOCRender()
{
	if (!m_pWindowHandler->HasFocus()) return false;		// Do not update when lost focus -- CRASH!!!
    
    
	bool	UseFilter = GetGraphics()->GetFilter2D();
	GetGraphics()->SetFilter2D(UseFilter);
	GetGraphics()->Start2D();
	GetGraphics()->Clear(0xFFFFFFFF);
    
	// ADRIAN: safe BeginScene check
	return (GetGraphics()->BeginScene());
}

bool		GameApp::EndOOCRender()
{
	FontManager::Instance().RenderCache();
	dd::Manager::Instance().Render2D();
	GetGraphics()->EndScene();
	GetGraphics()->Present();
    bool	UseFilter = GetGraphics()->GetFilter2D();
	GetGraphics()->SetFilter2D(UseFilter);	
	return true;
}

void		GameApp::UpdateOOC(const char*  _Msg, ...)
{
	if (!StartOOCRender()) return;
    
	char Message[1024];
	va_list ArgP;
	va_start(ArgP, _Msg);
	vsprintf(Message, _Msg, ArgP);
	va_end(ArgP);
    
	Font*	pFont = FontManager::Instance().GetFont("BigFont");
	if (!pFont) 
	{
		pFont = FontManager::Instance().GetDefaultFont();
		if (!pFont) return;
	}
	pFont->RenderCentered(Message, math::Vec2(0.5f, 0.5f), math::Vec2(0.6f,1));
    
	EndOOCRender();
}


void		GameApp::UpdateLoadBar(int	UnitsAdded)
{
	if (!StartOOCRender()) return;
	m_CurrentRate += UnitsAdded;
	float Progress = (float)m_CurrentRate / (float) m_TargetRate;
	if (m_pLoadingProgress)
	{
		m_pLoadingProgress->SetProgress(Progress);
	}
	if (m_pLoadingBackground)
	{
		m_pLoadingBackground->SetIsVisible(false);
		m_pLoadingBackground->Render(true);
	}
    
    //
    //#ifdef _PLATFORM_WII
    //	FontManager::Instance().Print(math::Vec2(0.01f, 0.04f), WiiMMGR_ToString());
    //#endif //
    
	EndOOCRender();
}

bool GameApp::ShutdownWindow()
{
	GetGraphics()->ShutdownWindow();
	/// flush anything else
	return true;
}

bool	GameApp::SetupWindow()
{
    // init graphics
	if (!CanDoFullscreen()) m_IsFullscreen = false;
    
	if (m_IsFullscreen && m_pWindowHandler->IsWidescreen()) 
	{
		// and do what with it?
		unsigned int	Width = m_pWindowHandler->GetWidth();
		unsigned int	Height = m_pWindowHandler->GetHeight();
		GetGraphics()->GetBestWideScreenRes(Width,Height);
		m_pWindowHandler->SetWidth(Width);
		m_pWindowHandler->SetHeight(Height);
	}
	Graphics::s_PixelOffsetX = (m_pWindowHandler->GetWidth() - m_pWindowHandler->ScreenWidth()) / 2;
	Graphics::s_PixelOffsetY = (m_pWindowHandler->GetHeight() - m_pWindowHandler->ScreenHeight()) / 2;
	GetGraphics()->SetOriginalPixelOffset(Graphics::s_PixelOffsetX, Graphics::s_PixelOffsetY);
    
	bool Works = GetGraphics()->InitWindow(m_pWindowHandler->GetWidth(), m_pWindowHandler->GetHeight(), m_IsFullscreen);
	if (!Works)
	{
		if (m_IsFullscreen)	// some machines may have problems running in fullscreen
		{
			_LOG(MSG_ERROR, "**** UNABLE TO START FULLSCREEN ****");
			_LOG(MSG_ERROR, "**** Forcing windowed mode ****");
			m_IsFullscreen = false;
			// ADRIAN: restore desktop res first
			if (m_pWindowHandler->IsResolutionChanged())
				m_pWindowHandler->RestoreResolution();
			// ADRIAN: reset pixel offsets
			Graphics::s_PixelOffsetX = 0;
			Graphics::s_PixelOffsetY = 0;
			GetGraphics()->SetOriginalPixelOffset(0, 0);
			// ADRIAN: also reset window parameters
			m_pWindowHandler->SetWidth(m_pWindowHandler->ScreenWidth());
			m_pWindowHandler->SetHeight(m_pWindowHandler->ScreenHeight());
			Works = GetGraphics()->InitWindow(m_pWindowHandler->GetWidth(), m_pWindowHandler->GetHeight(), m_IsFullscreen);
		}
		if (!Works)
		{
#ifdef _PLATFORM_WIN32
			MessageBox(NULL, 
                       "We had a problem initializing the window. It looks like we won't be able to start the game. ", 
                       "Unable to init DX8", MB_OK);
#endif //_PLATFORM_WIN32
			return false;
		}
	}
    
	GetGraphics()->RegisterFormats();
    
	if (GetGraphics()->GetGraphicsClass() < Graphics::GRAPHICS_CLASS_DX7)
	{
		GetGraphics()->SetFilter2D(false);
	} else
	{
		GetGraphics()->SetFilter2D(true);
	}
    
	m_pWindowHandler->SetFullscreen(m_IsFullscreen);
	return true;
}

bool		GameApp::InitGraphics()
{
	m_IsFullscreen = m_pRMS->IsUseFullscreenEnabled();
    
	if (!m_pWindowHandler->InitGraphics()) return false;
	if (!SetupWindow()) return false;
    
    
	// boot loader?
	_LOG(MSG_INIT, "Input initializes");
    
	OnCreateSplash();
    
	// draw the loading screen here quickly
	ui::SpriteSet::Instance().AddSet("ui_img/loadingsprites.lua",false);
	m_pLoadingBackground = ui::UIManager::Instance().AddPanel("ui/loading.ui");
	if (m_pLoadingBackground)
	{
		m_pLoadingProgress = m_pLoadingBackground->GetProgressByName("LoadingProgress");
		//UpdateLoadBar(0);
		m_pLoadingBackground->Tick(0);
	}
	
    
	OnInitFonts();
    
	console::Console::Instance().Init("scripts/console.lua", "verdana");
	LuaPlus::LuaState*	pScript = console::Console::Instance().GetScript();
	assert(m_pScript);
	m_pScript->Register(pScript);
	//GameAppScript::RegisterAll(pScript);
	std::string		Lang = GameRMS::Instance()->GetLanguage();
	if (Lang.empty())	Lang = "english";	// last ditch salvage
	console::Console::Instance().Do("OnStartUp()");
	console::Console::Instance().Do("SetupLanguage('"+Lang+"');");
    
    
	_LOG(MSG_INIT, "Console initialized");
	// CHIT: do we really need this?
	//lang::Swear::Instance().Load("scripts/swear.lua");
    
    
	// create a camera
	m_pCamera = new camera::FbCamera();
	math::Vec3 ClearColor = math::Vec3(0.1f, 0.1f, 0.3f);
    m_pCamera->SetClearColor(ColorRGBA((int)(ClearColor.x * 255), (int)(ClearColor.y * 255), (int)(ClearColor.z * 255)));
	m_pCamera->SetLookAt(math::Vec3(0, 20, -20), math::Vec3(0, 0, 0), math::Vec3(0, 1, 0));
	m_pCamera->SetProjection(30.0f, (float)4.0f/3.0f, math::Vec2(5, 4000));
    
	return true;
}

void		GameApp::InitSystems()
{
	m_pScript = new GameScript();
}

GameRMS*	GameApp::CreateRMS()
{
	return new GameRMS();
}

bool		GameApp::IsCheating()
{
	if (m_pRMS)
	{
		return m_pRMS->IsCheating();
	}
	return true;
}


////////////////////////////////////////////////////////////////////
// standard UI callback functions

void DELEGATE_CALL	GameApp::OnCloseSettings(ui::UIWidget::WIDGET_EVENT Event, ui::UIWidget* pWidget)
{
	GameRMS::Instance()->Save();
	UIPopupManager::Instance().HideAllPopups();
}

void DELEGATE_CALL	GameApp::OnSettingsTilt(ui::UIWidget::WIDGET_EVENT Event, ui::UIWidget* pWidget)
{
	GetRMS()->SetEnableTilt(!GetRMS()->IsTiltEnabled() );
    
	if(pWidget)
	{
		if(ui::UICheckBox* pCB = pWidget->GetPanel()->GetCheckBoxByName("TiltOn"))
		{
			pCB->SetChecked(GetRMS()->IsTiltEnabled());
		}
	}
    
}

void DELEGATE_CALL	GameApp::OnSettingsVibrate(ui::UIWidget::WIDGET_EVENT Event, ui::UIWidget* pWidget)
{
	GetRMS()->SetEnableVibrate(!GetRMS()->IsVibrateEnabled());
	if(pWidget)
	{
		if(ui::UICheckBox* pCB = pWidget->GetPanel()->GetCheckBoxByName("VibrationOn"))
		{
			pCB->SetChecked(GetRMS()->IsVibrateEnabled());
		}
	}
}


void DELEGATE_CALL	GameApp::OnSettingsFullscreen(ui::UIWidget::WIDGET_EVENT Event, ui::UIWidget* pWidget)
{
	if (!pWidget) return;
	// flip fullscreen setting
	
	bool	Fullscreen = !GetRMS()->IsUseFullscreenEnabled();	 
	if(Fullscreen)
	{
		m_pWindowHandler->SwitchFullscreen( m_pWindowHandler->GetWidth(), m_pWindowHandler->GetHeight() );
	}
	else 
	{
		m_pWindowHandler->SwitchWindowed(m_pWindowHandler->GetWidth(), m_pWindowHandler->GetHeight());
	}
    
    
	GetRMS()->SetUseFullscreenEnabled(Fullscreen);
}

void DELEGATE_CALL	GameApp::OnSettingsHelp(ui::UIWidget::WIDGET_EVENT Event, ui::UIWidget* pWidget)
{
	GetRMS()->SetEnableHint(!GetRMS()->IsHintEnabled());
}

void DELEGATE_CALL	GameApp::OnSettingsSFXVolumeChanged(ui::UIWidget::WIDGET_EVENT Event, ui::UIWidget* pWidget)
{
	if (pWidget->GetType() != ui::UIWidget::WT_SLIDER) return;
	ui::UISlider*	pSlider = (ui::UISlider*)pWidget;
	AUDIO().SetSFXVolume(int(pSlider->GetSlider() * 100));
	GetRMS()->SetSoundVolume(float(pSlider->GetSlider() * 100));
}

void DELEGATE_CALL	GameApp::OnSettingsMusicVolumeChanged(ui::UIWidget::WIDGET_EVENT Event, ui::UIWidget* pWidget)
{
	if (pWidget->GetType() != ui::UIWidget::WT_SLIDER) return;
	ui::UISlider*	pSlider = (ui::UISlider*)pWidget;
	AUDIO().SetMusicVolume(int(pSlider->GetSlider() * 100));
	GetRMS()->SetMusicVolume(float(pSlider->GetSlider() * 100));
}

void DELEGATE_CALL	GameApp::OnSettingsSFXToggle(ui::UIWidget::WIDGET_EVENT Event, ui::UIWidget* pWidget)
{
	if (pWidget->GetType() != ui::UIWidget::WT_CHECKBOX) return;
	ui::UICheckBox*	pChekBox = (ui::UICheckBox*)pWidget;
	int Val = 50;
	if(!pChekBox->IsChecked())
		Val = 0;
	AUDIO().SetSFXVolume((int)Val);
	GetRMS()->SetSoundVolume(( float)Val);
}
	
void DELEGATE_CALL	GameApp::OnSettingsMusicToggle(ui::UIWidget::WIDGET_EVENT Event, ui::UIWidget* pWidget)
{
	if (pWidget->GetType() != ui::UIWidget::WT_CHECKBOX) return;
	ui::UICheckBox*	pCheckBox = (ui::UICheckBox*)pWidget;
	int Val = 50;
	if(!pCheckBox->IsChecked())
		Val = 0;
	AUDIO().SetMusicVolume((int)Val);
	GetRMS()->SetMusicVolume(( float)Val);
}

void DELEGATE_CALL	GameApp::OnLanguageInit(ui::UIMover*	pMove)
{
    
}

void DELEGATE_CALL	GameApp::OnOpenSettings(gameflow::GameTransition*	pTrans)
{
	UIPopupManager::Instance().StartPopup("Settings");
}

void DELEGATE_CALL	GameApp::OnQuitGame(ui::UIWidget::WIDGET_EVENT Event, ui::UIWidget* pWidget)
{
#ifdef _PLATFORM_WIN32
	UIPopupManager::Instance().StartYesNo("QUIT_YES_NO", UI_DELEGATE(GameApp, OnQuitGameYes), NULL);
#endif
}

void DELEGATE_CALL	GameApp::OnQuitGameYes(ui::UIWidget::WIDGET_EVENT Event, ui::UIWidget* pWidget)
{
	GetHandler()->DestroyWindow();
}

void DELEGATE_CALL	GameApp::OnStartProfile(ui::UIWidget::WIDGET_EVENT Event, ui::UIWidget* pWidget)
{
	
}

void DELEGATE_CALL	GameApp::OnReturnMenu(ui::UIWidget::WIDGET_EVENT Event, ui::UIWidget* pWidget)
{
	UIPopupManager::Instance().HideAllPopups();
	//ui::UIManager::Instance().HideAll();
	gameflow::GameFlowManager::Instance().TransitionToState("MainMenu");
	
}

void DELEGATE_CALL	GameApp::OnCreateProfile(ui::UIWidget::WIDGET_EVENT Event, ui::UIWidget* pWidget)
{
    
	// check if it's all making sense
	UIPopupManager&		PM = UIPopupManager::Instance();
	UIPopup*	pCreate  = PM.GetPopup("CreateProfile");
	if (pCreate)
	{
		ui::UIWidget*	pName = pCreate->GetWidget("Name");
		ui::UIWidget*	pLoc = pCreate->GetWidget("LOC");
		std::string	Name, Loc;
		if (pName) Name = pName->GetTextA();	// store this as Widechar instead?
		if (pLoc) Loc = pLoc->GetTextA();
        
		// TODO: some sanity checks:
		// 1. Check length of name?
		if (Name.size() < 3)
		{
			PM.StartPrompt("NAME_TOO_SHORT", "NAME_TOO_SHORT_TXT", "OK", NULL);
			return;
		}
		// 2. Check if already exists?
        
		// store the new name
	}
	// everything okay, store and leave
	PM.EndPopup("CreateProfile");
}
//////////////////////////////////////////
// utility functions
void		GameApp::SetupSettingsUI(ui::UIWidget*	pPanel, bool SetupLogic)
{
	if (!pPanel) return;
    
	if (ui::UICheckBox*	pHints = pPanel->GetCheckBoxByName("HintsOn"))
	{
		pHints->SetChecked(GetRMS()->IsHintEnabled());
	}
    
    if (ui::UICheckBox*	pFullscreen = pPanel->GetCheckBoxByName("FULLSCREEN_ON"))
#if  defined(_PLATFORM_IOS) || defined(_PLATFORM_ANDROID)
	{
        pFullscreen->SetChecked(false);
		
	}
#else
        pFullscreen->SetChecked(IsFullscreen());
#endif
    
	if (ui::UICheckBox*	pHints = pPanel->GetCheckBoxByName("HintsOn"))
	{
		pHints->SetChecked(GetRMS()->IsHintEnabled());
	}
    
	if (ui::UICheckBox*	pTilt = pPanel->GetCheckBoxByName("TiltOn"))
	{
		if(GetRMS()->GetCanTilt())
		{
			pTilt->SetChecked(GetRMS()->IsTiltEnabled());
		}
		else
		{
			
			if(GetRMS())
				GetRMS()->SetEnableTilt(false);

			
			pTilt->SetChecked(false);
			pTilt->SetIsActive(false);
			pTilt->SetColor(0.7f,0.7f,0.7f,0.5f);
			if( ui::UIWidget* pText = pPanel->GetWidgetByName("TILT_TEXT"))
			{
				pText->SetTextColor(0.7f,0.7f,0.7f,0.7f);	
				pText->SetIsActive(false);
			}
		}
	}
	if (ui::UICheckBox*	pVib = pPanel->GetCheckBoxByName("VibrationOn"))
	{
//#if defined( _PLATFORM_ANDROID) // not yet finish implementing    // for now deprecated IOS as well
		pVib->SetIsVisible(false);
//#endif
		if(GetRMS()->GetCanVibrate())
		{
			pVib->SetChecked(GetRMS()->IsVibrateEnabled());			
		}
		else
		{
			GetRMS()->SetEnableVibrate(false);
			pVib->SetChecked(false);
			pVib->SetIsActive(false);
			pVib->SetColor(0.7f,0.7f,0.7f,0.5f);
			if( ui::UIWidget* pText = pPanel->GetWidgetByName("VIBRATION_TEXT"))
			{
				pText->SetTextColor(0.7f,0.7f,0.7f,0.7f);
				pText->SetIsActive(false);
			}
		}
	}
    
	if (ui::UICheckBox*	pMusicVolumeOn = pPanel->GetCheckBoxByName("Music_volume1"))
	{
		pMusicVolumeOn->SetChecked(GetRMS()->GetMusicVolume() > 5.0f);
		if (SetupLogic)
			pMusicVolumeOn->SetReleaseLMBEventDg(UI_DELEGATE(GameApp, OnSettingsMusicToggle));
	}
	if (ui::UISlider*	pMusicVolume = pPanel->GetSliderByName("Music_volume2"))
	{
		pMusicVolume->SetSlider(GetRMS()->GetMusicVolume() / 100.0f);
		if (SetupLogic)
			pMusicVolume->SetSliderChangeEventDg(UI_DELEGATE(GameApp, OnSettingsMusicVolumeChanged));
	}
	if (ui::UICheckBox*	pSFXVolumeOn = pPanel->GetCheckBoxByName("Sound_volume1"))
	{
		pSFXVolumeOn->SetChecked(GetRMS()->GetSoundVolume() > 5.0f);
		if (SetupLogic)
			pSFXVolumeOn->SetReleaseLMBEventDg(UI_DELEGATE(GameApp, OnSettingsSFXToggle));
	}
	if (ui::UISlider*	pSFXVolume = pPanel->GetSliderByName("Sound_volume2"))
	{
		pSFXVolume->SetSlider(GetRMS()->GetSoundVolume() / 100.0f);
		if (SetupLogic)
			pSFXVolume->SetSliderChangeEventDg(UI_DELEGATE(GameApp, OnSettingsSFXVolumeChanged));
	}
	// all beyond here sets up sliders, etc
	if (!SetupLogic) return;
	UIPopup*	pSettings =  UIPopupManager::Instance().GetPopup("Settings");
	if (!pSettings) return;
    
	// setup the buttons here
	pSettings->SetWidgetFunctor("FULLSCREEN_ON", UI_DELEGATE(GameApp, OnSettingsFullscreen));
	pSettings->SetWidgetFunctor("HintsOn", UI_DELEGATE(GameApp, OnSettingsHelp));
	pSettings->SetWidgetFunctor("TiltOn", UI_DELEGATE(GameApp, OnSettingsTilt));
	pSettings->SetWidgetFunctor("VibrationOn", UI_DELEGATE(GameApp, OnSettingsVibrate));	
	
	pSettings->SetWidgetFunctor("TILT_TEXT", UI_DELEGATE(GameApp, OnSettingsTilt));
	pSettings->SetWidgetFunctor("VIBRATION_TEXT", UI_DELEGATE(GameApp, OnSettingsVibrate));	
    
	pSettings->SetWidgetFunctor("Resume", UI_DELEGATE(GameApp, OnCloseSettings));
    
    
	// setup the transition popups
	pSettings->SetupTransition("Credits", "credits");
	pSettings->SetWidgetPopup("Language", "Language", NULL, UIMOVER_DELEGATE(GameApp, OnLanguageInit));
	
}

void		GameApp::SetupReturnWidget(ui::UIWidget* pWidget)
{
	if (pWidget)
	{
		pWidget->SetReleaseLMBEventDg(UI_DELEGATE(GameApp, OnReturnMenu));
	}
    
}

void		GameApp::SetupUI()
{
	GameFlowManager&	GM = GameFlowManager::Instance();
	UIPopupManager&		PM = UIPopupManager::Instance();
	// load the popups
	UIPopup*	pSettings			= PM.AddPopup("ui/settings.ui", "Resume");
	UIPopup*	pLanguage			= PM.AddPopup("ui/language.ui","Resume");

    // we don't use it for now in those platform.
#if !defined(_PLATFORM_IOS) && !defined (_PLATFORM_ANDROID)
	UIPopup*	pProfile			= PM.AddPopup("ui/profile.ui");
	UIPopup*	pCreateProfile		= PM.AddPopup("ui/createprofile.ui");
	UIPopup*	pPrompt				= PM.AddPopup("ui/prompt.ui", "btn_ok");
#else
    UIPopup*	pProfile		= NULL;
    UIPopup*	pCreateProfile  = NULL;
	UIPopup*	pPrompt			= NULL;
#endif
    
	
	UIPopup*	pYesNo				= PM.AddPopup("ui/yesno.ui");
    
    
	// fast loads
	//PM.AddPopup("ui/gameui.ui");
    
	// setup UI logic
	SetupSettingsUI(pSettings->GetPanel(), true);
    
	if (pCreateProfile)
	{
		pCreateProfile->SetWidgetFunctor("OKWidget", UI_DELEGATE(GameApp, OnCreateProfile));
	}
    
    
	// setup all the different UI states that are part of the normal framework
	UIState*	pMain = (UIState*)GM.AddTransitionState("MainMenu",GetGameStateMainMenu());
	pMain->SetWidgetPopup("HIGHSCORE", "createprofile");
	pMain->SetWidgetPopup("SETTINGS", "settings");
	pMain->SetWidgetPopup("CHANGE_USER", "createprofile", NULL);	// setup profile as well
    
	pMain->SetWidgetFunctor("QUIT_GAME", UI_DELEGATE(GameApp, OnQuitGame));
    
	UIState*	pCredits = (UIState*)GM.AddTransitionState("credits",	new CreditState(m_pCamera));
	if(pCredits)
		pCredits->SetupTransition("ReturnWidget", "MainMenu", "", TRANSITION_DELEGATE(GameApp, OnOpenSettings));
    
	
	///	UIState*	pMain = (UIState*)GM.AddTransitionState("MainMenu", new UIState(m_pCamera, "ui/main_menu.ui"));
    
    
    
}

gameflow::GameState*		GameApp::GetGameStateMainMenu()
{
	 return new UIState(m_pCamera, "ui/main_menu.ui");
}


